import { fetchErrLog } from '../log';
import axios, { AxiosResponse } from 'axios';
import { IFetchError, TFetchMethod } from './type';
import { requestOnFulfilled, requestOnRejected, responseOnFulfilled, responseOnRejected } from './interceptors';

// Fetch 实例
const axiosInstance = axios.create({
    timeout: 30000,
    headers: { 'Content-Type': 'application/json' },
});

// 拦截器
axiosInstance.interceptors.request.use(requestOnFulfilled, requestOnRejected);
axiosInstance.interceptors.response.use(responseOnFulfilled, responseOnRejected);

// 业务通用处理（外部处理）
function fetchOnFulfilled(response: AxiosResponse) {
    const responseData: unknown = response.data;
    return Promise.resolve(responseData);
}

// 请求异常处理（内部处理）
function fetchOnRejected(fetchError: IFetchError) {
    switch (fetchError.type) {
        case 'request': {
            // 404
            // 503
            // ...
            break;
        }
        case 'response': {
            const { message } = fetchError.error;
            if (message.includes('timeout')) {
                // timeout
            } else {
                // 500
                // ...
            }
        }
    }

    fetchErrLog(fetchError.error);

    return Promise.reject(null);
}

// Fetch
async function fetch(method: TFetchMethod, url: string, data: unknown = {}, headers = {}): Promise<unknown> {
    try {
        const response = await axiosInstance.request({ method, url, data, headers, baseURL: '' });
        return fetchOnFulfilled(response);
    } catch (fetchError: any) {
        return fetchOnRejected(fetchError);
    }
}

// Method
export default {
    get(url: string, data?: unknown, headers?: Record<string, string>): Promise<any> {
        return fetch('get', url, data, headers);
    },
    post(url: string, data?: unknown, headers?: Record<string, string>): Promise<any> {
        return fetch('post', url, data, headers);
    },
};
